use rusqlite::Row;

use crate::dao;
use crate::models::models::command::{Command, CommandState};
use crate::runtime::error::MagicBoxError;
use crate::runtime::response::Code;
use crate::runtime::result::MagicBoxResult;

/// 插入历史命令
pub(crate) fn insert_command_history(command: &Command) -> MagicBoxResult<()> {
    let connection = dao::connection::main();

    let result = connection.execute("insert into commands(command_id, name, args, output, state, component) values (?1, ?2, ?3, ?4, ?5, ?6)", (command.command_id.clone(), command.name.clone(), command.args.clone(), command.output.clone(), command.state.clone(), command.component.clone()));
    if result.is_err() {
        log::error!("插入历史命令失败: {:?}", result.err());

        return Err(MagicBoxError::new(Code::UndefinedError, "数据库错误"));
    }

    Ok(())
}

/// 更新历史命令
pub(crate) fn update_command_history(command: &Command) -> MagicBoxResult<()> {
    let connection = dao::connection::main();

    let result = connection.execute("update commands set output = ?1, state = ?2, statistic = ?3 where command_id = ?4", (command.output.clone(), command.state.clone(), command.statistic.clone(), command.command_id.clone()));
    if result.is_err() {
        log::error!("更新历史命令失败: {:?}", result.err());

        return Err(MagicBoxError::new(Code::UndefinedError, "数据库错误"));
    }

    Ok(())
}

/// 获取历史命令
pub(crate) fn get_command_history(cnt: usize) -> MagicBoxResult<Vec<Command>> {
    let connection = dao::connection::main();

    let mut statement = connection.prepare("select id, command_id, name, args, output, state, component, statistic from commands order by id desc limit ?1").unwrap();
    let result = statement.query_map([cnt], parse_row_to_command);

    if result.is_err() {
        let err = result.err().unwrap().to_string();
        log::error!("获取历史命令失败: {}", err.as_str());

        return Err(MagicBoxError::new(Code::UndefinedError, format!("获取历史命令失败: {}", err.as_str()).as_str()));
    }

    let result = result.unwrap();
    let mut commands: Vec<Command> = Vec::new();
    for row in result {
        if row.is_err() {
            let err = row.unwrap_err().to_string();
            log::error!("获取历史命令失败: {}", err.as_str());

            return Err(MagicBoxError::new(Code::UndefinedError, format!("获取历史命令失败: {}", err.as_str()).as_str()));
        }

        commands.push(row.unwrap());
    }

    Ok(commands)
}

/// 获取最近的N条AI命令
pub(crate) fn get_last_ai_commands(count: usize) -> MagicBoxResult<Vec<Command>> {
    let connection = dao::connection::main();

    let mut statement = connection.prepare("select id, command_id, name, args, output, state, component, statistic from commands where name = ?1 order by id desc limit ?2").unwrap();
    let result = statement.query_map(["ai", &count.to_string()], parse_row_to_command);
    if result.is_err() {
        let err = result.err().unwrap().to_string();
        log::error!("获取最近的N条AI命令失败: {}", err.as_str());

        return Err(MagicBoxError::new(Code::UndefinedError, format!("获取AI命令历史失败: {}", err.as_str()).as_str()));
    }

    let result = result.unwrap();
    let mut commands: Vec<Command> = Vec::new();
    for row in result {
        if row.is_err() {
            let err = row.err().unwrap().to_string();
            log::error!("获取AI历史命令失败: {}", err.as_str());

            return Err(MagicBoxError::new(Code::UndefinedError, format!("获取AI历史命令失败: {}", err.as_str()).as_str()));
        }

        commands.push(row.unwrap());
    }

    Ok(commands)
}

/// 解析Row到Command
fn parse_row_to_command(row: &Row) -> rusqlite::Result<Command> {
    let mut command = Command::default();

    command.id = row.get::<_, u64>(0)?;
    command.command_id = row.get::<_, String>(1)?;
    command.name = row.get::<_, String>(2)?;
    command.args = row.get::<_, String>(3)?;
    command.output = row.get::<_, String>(4)?;
    command.state = row.get::<_, CommandState>(5)?;
    command.component = row.get::<_, String>(6)?;
    command.statistic = row.get::<_, String>(7)?;

    Ok(command)
}